{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 时间模块 `chrono`\n",
    "\n",
    "`chrono` 库，包含一系列和时钟、日期相关的功能。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "#include <chrono>\n",
    "#include <thread>\n",
    "using namespace std::chrono;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`chrono` 库里包括三种主要类型：clocks，time points 和 durations。\n",
    "\n",
    "一个时钟（`clock`）包含了两部分：时钟原点和时钟节拍。时钟原点通常是 1970-01-01 00:00:00 UTC，一段时间的时钟节拍数除以振动频率，可以得到这段时间的具体时间。\n",
    "\n",
    "C++ 定义了三种类型的时钟：\n",
    "\n",
    "- `std::chrono::system_clock`：本地系统的当前时间(可以调整)\n",
    "- `std::chrono::steady_clock`：不能被调整的，稳定增加的时间。表示过去某个时间点到现在之间的时间，这个时间不能被调整，物理时间增加，它一定增加，而且与系统时间无关（可以是系统重启以来的时间段），最适合于计算程序的耗时时长。\n",
    "- `std::chrono::high_resolution_clock`：高精度的计时周期\n",
    "\n",
    "每个 `clock` 类中都有确定的 `time_point`、 `duration`、 `Rep`、 `Period` 类型，这些类型后面都会讲到。\n",
    "\n",
    "`std::chrono::system_clock` 和 `std::chrono::steady_clock` 时钟类都提供了静态成员函数 {func}`now` 用于获取当前时间，该函数的返回值都是 `time_point` 类型，`system_clock` 还另外提供了两个支持系统时间和 `std::time_t` 相互转换的静态成员函数：{func}`to_time_t`() 和 {func}`from_time_t`。\n",
    "\n",
    "获取时间间隔可以："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "运行时间: 2.00015s"
     ]
    }
   ],
   "source": [
    "time_point<system_clock> start = system_clock::now();\n",
    "// 模拟耗时\n",
    "std::this_thread::sleep_for(std::chrono::seconds(2));\n",
    "time_point<system_clock> end = system_clock::now();\n",
    "// 获取间隔时间\n",
    "std::chrono::duration<double> elapsed = end - start;\n",
    "// 打印时间信息\n",
    "std::cout << \"运行时间: \" << elapsed.count() << \"s\";"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`sleep_for` 用于使主线程休眠，休眠时间由 `std::chrono::seconds()` 控制。\n",
    "\n",
    "也可以查看系统时间："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Thu Sep 29 10:54:37 2022\n",
      "2022 年 9 月 29 日 10 时 54 分 37 秒 "
     ]
    }
   ],
   "source": [
    "auto t = std::chrono::system_clock::now();\n",
    "std::time_t tt = std::chrono::system_clock::to_time_t(t);\n",
    "std::string stt = std::ctime(&tt);\n",
    "std::cout << stt; // 默认格式\n",
    "std::tm* now = std::gmtime(&tt);\n",
    "std::cout << now->tm_year+1900 << \" 年 \"\n",
    "          << now->tm_mon+1 << \" 月 \"\n",
    "          << now->tm_mday << \" 日 \"\n",
    "          << now->tm_hour << \" 时 \"\n",
    "          << now->tm_min << \" 分 \"\n",
    "          << now->tm_sec << \" 秒 \";"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 持续时间\n",
    "\n",
    "`std::chrono::duration` 是模板类，从名字都可以看出来，它表示时间间隔。\n",
    "\n",
    "使用参数 `Rep` 和 `Period` 共同表示时间间隔。\n",
    "\n",
    "- `Rep` 用于指定数值类型，表示节拍的数量；\n",
    "- `Period` 属于 `std::ratio` 类型，表示单位精度，用来计算一个节拍的周期，`std::ratio` 是分数类型的模板类，包含分子（Num）和分母（Denom）两部分。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "运行时间: 2.00016s"
     ]
    }
   ],
   "source": [
    "time_point<steady_clock> start = steady_clock::now();\n",
    "// 模拟耗时\n",
    "std::this_thread::sleep_for(std::chrono::seconds(2));\n",
    "time_point<steady_clock> end = steady_clock::now();\n",
    "// 获取间隔时间\n",
    "std::chrono::duration<double> elapsed = end - start;\n",
    "// 打印时间信息\n",
    "std::cout << \"运行时间: \" << elapsed.count() << \"s\";"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++14",
   "language": "C++14",
   "name": "xcpp14"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "14"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
